<?php
/**
 * Created by PhpStorm.
 * User: liu
 * Date: 17-4-1
 * Time: 上午8:58
 */

namespace Cframe;


class ShotTag{
    private $tag = [];
    public function addTag($name = '',callable $caller){
        $this->tag[$name] = $caller;
    }

    public function parseTag(&$content){
        foreach ($this->tag as $key=>$value){
            $reg = $this->getReg($key);
            $this->parsing($reg,$content,$value);
        }
    }

    private function getReg($name){
        $end = '\]';
        $start = '\[';
        return "/" . $start . '(?:(' . $name . ')\b(?>(?:(?!' . $end . ').)*)|\/(' . $name . '))' . $end . "/is";
    }

    private function getP($content = ''){
        $reg = "/\s+(?>(?P<name>[\w-]+)\s*)=(?>\s*)([\"'])(?P<value>(?:(?!\\2).)*)\\2/is";
        preg_match_all($reg,$content,$match);
        foreach ($match as $k=>$v){
            if (is_numeric($k)){
                unset($match[$k]);
            }
        }
        return $match;
    }

    private function parsing($reg,&$content = '',callable $function){
        $end = '';
        $name = '';
        $break = "####content####";
        if (preg_match($reg,$content)){
            $content = preg_replace_callback($reg,function ($match) use (&$end,$break,$function,&$name){
                if (isset($match[1]) && !empty($match[1])){
                    $name = $match[1];
                    $arr = $this->getP($match[0]);
                    $data = call_user_func($function,$arr,$break);
                    $data = explode($break,$data);
                    $end = end($data);
                    return $data[0];
                }elseif (!empty($name)){
                    return $end;
                }
            },$content);
        }
    }

}